home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 8281 < prev    next >
Encoding:
Text File  |  1996-08-05  |  8.5 KB  |  258 lines

  1. Path: daily-planet.execpc.com!usenet
  2. From: sprecher@execpc.com (Reginald W. Sprecher)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: What is &Variable (declared as: char Variable[10])?
  5. Date: Sat, 02 Mar 1996 23:00:52 GMT
  6. Organization: A.C.M.E Consulting
  7. Message-ID: <4hagqg$6je@daily-planet.execpc.com>
  8. References: <4gqpa1$3h9@alcor.usc.edu>
  9. NNTP-Posting-Host: stickleback.execpc.com
  10. X-Newsreader: Forte Free Agent 1.0.82
  11.  
  12. I am sure that many of you will protest about what I am about to say
  13. about pointers but it is my intention to try and clarify what all the
  14. fuss is about.
  15.  
  16. First off we need to start with some definitions.
  17.  
  18. 1.  A pointer - a pointer is a variable which has as its purpose the
  19. ability to point to another variable.  One thing that needs to be made
  20. clear here is that the size of a pointer is always the same no matter
  21. what type of data the pointer is pointing at ( a pointer to a char and
  22. an int are the same size). However, this is not and will not hold
  23. across machines.  For example, a pointer on an pc-xt type computer
  24. would be different from a pentium computer.  This is because the
  25. pointer needs to be able to hold an address to something.  If the
  26. memory space in a target machine is 16 bits then a pointer for that
  27. machine is 16 bits.  If the memory space on a different machine is 32
  28. bits then the size of the pointer is 32 bits.  
  29.  
  30. 2. address - all variables, including pointers and arrays, have a
  31. address as to where they live in memory.
  32.  
  33. 3. & - the & is the 'give me the address where the indicated variable
  34. lives in memory' command.  All variables live in memory and therefore
  35. have an address.  This address can only be resolved at runtime.
  36.  
  37. =========================================================
  38.  
  39. Now lets walk through a small program.  (assume for this discussion
  40. that we are running on a 16 bit machine, aka pc-xt.
  41.  
  42. void main(void)
  43. {
  44.  
  45.   int a;
  46.   int b[3];
  47.   char c[4];
  48.   char  *a_pointer;
  49.  
  50.   a = sizeof(b);
  51.   a = sizeof(c);
  52.  
  53.   a_pointer = c;       // or a_pointer = &c[0]
  54.  
  55.   scanf("%s",c);
  56.  
  57. }
  58.  
  59. 1.  The first four statement instructs our program to create memory
  60. for the indicated variables on the stack.  After these instructions
  61. are performed our memory looks like:
  62.  
  63.                        address     (our name)
  64. ________
  65. |                |     1000        a  (because a is an int we need 2 bytes to store it)
  66. |                |     1001
  67. -------------
  68. |                |     1002        b[0]  this is the first element of array b
  69. |                |     1003
  70. -------------
  71. |                |     1004        b[1]
  72. |                |     1005
  73. -------------
  74. |                |     1006        b[2]
  75. |                |     1007
  76. -------------
  77. |                |     1008        c[0]  this is a character array
  78. |                |     1009        c[1]  ( a character is only 1 byte big)
  79. -------------
  80. |                |     1010        c[2]
  81. |                |     1011        c[3]
  82. -------------
  83. |                |     1012        a_pointer (since we have assumed a
  84. |                |     1013             16 bit machine a pointer lives in 2 bytes
  85. -------------
  86.  
  87.  
  88. 2.  The next thing we encounter is the sizeof instructions.  Be
  89. carefull here, sizeof looks like a C runtime function, acts like a C
  90. runtime function but is not a C runtime function.  It is really some
  91. instructions to tell the compiler to calculate the size of the
  92. indicated variable at compile time and not at runtime.  It is because
  93. sizeof is performed by the compiler that the sizeof an array (or any
  94. variable) can be determined.
  95.  
  96. 3.  After the sizeof are done memory looks like..
  97.  
  98.                        address     (our name)
  99. ________
  100. |                |     1000        a  (because a is an int we need 2 bytes to store it)
  101. |     4         |     1001
  102. -------------
  103. |                |     1002        b[0]  this is the first element of array b
  104. |                |     1003
  105. -------------
  106. |                |     1004        b[1]
  107. |                |     1005
  108. -------------
  109. |                |     1006        b[2]
  110. |                |     1007
  111. -------------
  112. |                |     1008        c[0]  this is a character array
  113. |                |     1009        c[1]  ( a character is only 1 byte big)
  114. -------------
  115. |                |     1010        c[2]
  116. |                |     1011        c[3]
  117. -------------
  118. |                |     1012        a_pointer (since we have assumed a
  119. |                |     1013             16 bit machine a pointer lives in 2 bytes
  120. -------------
  121.  
  122.  
  123. 3)    a_pointer = c;       // or a_pointer = &c[0]
  124.  
  125. memory after this instruction is performed.
  126.  
  127.                        address     (our name)
  128. ________
  129. |                |     1000        a  (because a is an int we need 2 bytes to store it)
  130. |     4         |     1001
  131. -------------
  132. |                |     1002        b[0]  this is the first element of array b
  133. |                |     1003
  134. -------------
  135. |                |     1004        b[1]
  136. |                |     1005
  137. -------------
  138. |                |     1006        b[2]
  139. |                |     1007
  140. -------------
  141. |                |     1008        c[0]  this is a character array
  142. |                |     1009        c[1]  ( a character is only 1 byte big)
  143. -------------
  144. |                |     1010        c[2]
  145. |                |     1011        c[3]
  146. -------------
  147. |                |     1012        a_pointer (since we have assumed a
  148. |  1008     |     1013             16 bit machine a pointer lives in 2 bytes
  149. -------------
  150.  
  151. The crux of the problem.
  152.  
  153. Is the name of an array a pointer?  The answer to this, using our
  154. definition of what a pointer is, is no.  The name of an array is not a
  155. pointer, but it is what we would call an address.  This is because we
  156. define all arrays in terms of where they begin in memory.  Therefore
  157. the following expressions are equal
  158.  
  159.           c == &c[0]
  160. (1008) == (1008)  ----> from our memory map
  161.  
  162. This fact therefore makes it possible to intermix the following array
  163. notation:
  164.  
  165. c[1]  or *(c + 1)
  166.  
  167. again, c[1] gets the contents of array location 1.
  168. the other expression is evaulated as:
  169.  
  170. *(1008 + 1)
  171. *(1009)   ---> use 1009 as an address and gets whats there.  Looking
  172. at our memory map you will find that c[1] as at address 1009!
  173.  
  174. WARNING: The above expression is a specific interpretation of the more
  175. general form for a single dimension array:
  176.  
  177. *(array_name + (index * size_of_data_in_array))
  178.  
  179. in our example:
  180.  
  181. array_name = c or 1008
  182. index = 1
  183. data_in_array = char (each data item is 1 byte big)
  184.  
  185. *(1008 + (1 * 1))
  186. *(1008 + 1)
  187. etc....
  188.  
  189. Which can be generalized even further for multi-dimensional arrays:
  190. array_name[m][n]
  191.  
  192. * ( *(array_name + (m * size_of_data_in_array) ) + (n *
  193. size_of_data_in_array) )
  194.  
  195. 4.  Scanf is a function that says it wants 'a pointer' to a variable.
  196. What it really wants is the address of the variable where it (scanf)
  197. should put the data it has.  That is why the following scanf
  198. expressions will put the data in the same place:
  199.  
  200. scanf("%s",c);    AND  scanf("%s",a_pointer);
  201.  
  202. Evaulating the expressions:  c and a_pointer we get:
  203.  
  204. c = 1008 (address of array called c)
  205. a_pointer = 1008 (address of array called c)
  206.  
  207. Therefore the actual value that gets passed to the function scanf is
  208. 1008, or the address of the variable that should hold the data. 
  209.  
  210.  
  211.  
  212. =========================================================
  213.  
  214. Missconcepetions:
  215.  
  216.  
  217. 1)  Using the name of an array somehow yields or calculates or
  218. generates the address.
  219.  
  220. This is not true. The name of the array is the address of the array.
  221. The operation is not a calculation or de-referencing, or ....
  222. I have personally never heard of this 'decay' process.  If you look
  223. what is really happening inside the code there is no decay process.
  224. This is because the program always reference an array by its address
  225. which is the address of the first element in the array.  This same
  226. pricincipal applies to multi-dimensional arrays as well.
  227.  
  228.  
  229. 2)  &c is a pointer to something.
  230.  
  231. &c is by the above definition is not a pointer, it is an address, and
  232. specifically it is an address to a variable called c, which is of type
  233. char, and whose first element is at some address.
  234.  
  235. &c is the address of myarray which is:
  236.  
  237. &c == c == &c[0] == 1008 (in our memory map)
  238.  
  239. Any use of this information, be it calling this value that starts at
  240. 1008 as a single item of type character OR a collection of things of
  241. type chararcter is the responsiblity of the user of address (1008).
  242.  
  243. 3)  Pointer take on different sizes.
  244.  
  245. Pointers only take on a different size when going from one platform to
  246. another.  If you write a program and define 1000 pointers that can
  247. point at base data types or your own structures, the size (amount of
  248. memory) that the pointer varialbe it self consumes is still the same
  249. size.  Again, the factor here is what is the address space of your
  250. target system.
  251.  
  252. Reginald W. Sprecher
  253. A.C.M.E. Consulting
  254. Assembler, C/C++,Microprocessor,Embedded Consulting
  255. sprecher@execpc.com
  256.  
  257.  
  258.